package org.lpw.wormhole.util;

import java.io.InputStream;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * @author lpw
 */
public class ConfigurerImpl
    implements Configurer
{
    protected final int httpMaxThread;
    protected final int httpConnectionTimeout;
    protected final int httpReadTimeout;
    protected final int cacheAliveTime;
    protected final long maxMemory;
    protected final String[] remoteCacheUrl;
    protected final int queueMaxThread;
    protected final String[] remoteQueueUrl;

    public ConfigurerImpl(Kit kit)
    {
        super();

        Properties properties = new Properties();
        loadConfig(kit, properties);

        Pattern nonNegativeIntegerPattern = Pattern.compile("^[0-9]+$");
        httpMaxThread = getAsNonNegativeInteger(properties, "wormhole.http.max-thread", nonNegativeIntegerPattern, 5);
        httpConnectionTimeout = getAsNonNegativeInteger(properties, "wormhole.http.connection-timeout", nonNegativeIntegerPattern, 5);
        httpReadTimeout = getAsNonNegativeInteger(properties, "wormhole.http.read-timeout", nonNegativeIntegerPattern, 10);
        cacheAliveTime = getAsNonNegativeInteger(properties, "wormhole.cache.alive-in-minute", nonNegativeIntegerPattern, 0);
        Pattern bitPattern = Pattern.compile("^[0-9]+[tTgGmMkK]+$");
        maxMemory = getAsBit(properties, "wormhole.cache.max-memory", bitPattern, 1024L);
        remoteCacheUrl = getAsArray(properties, "wormhole.cache.remotes", kit);
        queueMaxThread = getAsNonNegativeInteger(properties, "wormhole.queue.max-thread", nonNegativeIntegerPattern, 5);
        remoteQueueUrl = getAsArray(properties, "wormhole.queue.remotes", kit);
    }

    protected void loadConfig(Kit kit, Properties properties)
    {
        try
        {
            InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("wormhole.config.properties");
            properties.load(input);
            input.close();
            input = null;
        }
        catch(Exception e)
        {
            kit.getLogger().warn(e, "读取Wormhole主配置文件[classpath:wormhole.config.properties]时发生异常！");
        }
    }

    @Override
    public int getHttpMaxThread()
    {
        return httpMaxThread;
    }

    @Override
    public int getHttpConnectionTimeout()
    {
        return httpConnectionTimeout;
    }

    @Override
    public int getHttpReadTimeout()
    {
        return httpReadTimeout;
    }

    @Override
    public int getCacheAliveTime()
    {
        return cacheAliveTime;
    }

    @Override
    public long getMaxMemory()
    {
        return maxMemory;
    }

    @Override
    public String[] getRemoteCacheUrl()
    {
        return remoteCacheUrl;
    }

    @Override
    public int getQueueMaxThread()
    {
        return queueMaxThread;
    }

    @Override
    public String[] getRemoteQueueUrl()
    {
        return remoteQueueUrl;
    }

    protected int getAsNonNegativeInteger(Properties properties, String key, Pattern nonNegativeIntegerPattern, int defaultValue)
    {
        String value = properties.getProperty(key);

        return value==null||!nonNegativeIntegerPattern.matcher(value).matches()?defaultValue:Integer.parseInt(value);
    }

    protected long getAsBit(Properties properties, String key, Pattern bitPattern, long defaultValue)
    {
        String value = properties.getProperty(key);

        if(value==null||!bitPattern.matcher(value).matches())
            return defaultValue;

        long number = Long.parseLong(value.substring(0, value.length()-1));
        char unit = value.charAt(value.length()-1);
        char[] units = {'t', 'T', 'g', 'G', 'm', 'M', 'k', 'K', 'b', 'B'};
        for(int i = 0; i<units.length-2; i += 2)
        {
            if(unit==units[i]||unit==units[i+1])
            {
                number *= 1024;
                unit = units[i+2];
            }
        }

        return number;
    }

    protected String[] getAsArray(Properties properties, String key, Kit kit)
    {
        String value = properties.getProperty(key);

        if(value==null||"".equals(value))
            return new String[0];

        return kit.getConverter().toArray(value, ",");
    }
}
